package com.eve.eplus.common.view;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.eve.eplus.R;
import com.eve.eplus.common.tools.ComTimeTools;
import com.eve.eplus.common.view.ScrollOverListView.OnScrollOverListener;

/**
 * 下拉刷新控件</br>
 * 真正实现下拉刷新的是这个控件，
 * ScrollOverListView只是提供触摸的事件等
 * 
 * @author
 */
public class PullDownView extends LinearLayout implements OnScrollOverListener
{

    private static final int START_PULL_DEVIATION = 50; // 移动误差
    private static final int AUTO_INCREMENTAL = 10; // 自增量，用于回弹

    private static final int WHAT_DID_LOAD_DATA = 1; // Handler what 数据加载完毕
    private static final int WHAT_ON_REFRESH = 2; // Handler what 刷新中
    private static final int WHAT_DID_REFRESH = 3; // Handler what 已经刷新完
    private static final int WHAT_SET_HEADER_HEIGHT = 4;// Handler what 设置高度
    private static final int WHAT_DID_MORE = 5; // Handler what 已经获取完更多

    private static final int DEFAULT_HEADER_VIEW_HEIGHT = 105; // 头部文件原本的高度

    private View mHeaderView;
    private LayoutParams mHeaderViewParams;
    private TextView mHeaderTextView;
    private View mHeaderLoadingView;
    private View mFooterView;
    private TextView mFooterTextView;
    private View mFooterLoadingView;
    private ScrollOverListView mListView;

    private OnPullDownListener mOnPullDownListener;

    private int mHeaderIncremental; // 增量
    private float mMotionDownLastY; // 按下时候的Y轴坐标

    private boolean mIsDown; // 是否按下
    private boolean mIsRefreshing; // 是否下拉刷新中
    private boolean mIsFetchMoreing; // 是否获取更多中
    private boolean mIsPullUpDone; // 是否回推完成
    private boolean mEnableAutoFetchMore; // 是否允许自动获取更多

    // 头部文件的状态
    private static final int HEADER_VIEW_STATE_IDLE = 0; // 空闲
    private static final int HEADER_VIEW_STATE_NOT_OVER_HEIGHT = 1; // 没有超过默认高度
    private static final int HEADER_VIEW_STATE_OVER_HEIGHT = 2; // 超过默认高度
    private int mHeaderViewState = HEADER_VIEW_STATE_IDLE;

    public PullDownView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        initHeaderViewAndFooterViewAndListView(context);
    }

    public PullDownView(Context context)
    {
        super(context);
        initHeaderViewAndFooterViewAndListView(context);
    }

    /*
     * ==================================
     * Public method
     * 外部使用，具体就是用这几个就可以了
     * 
     * ==================================
     */

    /**
     * 刷新事件接口
     * 
     * @author
     */
    public interface OnPullDownListener
    {
        void onRefresh();

        void onMore();
    }

    /**
     * 通知加载完了数据，要放在Adapter.notifyDataSetChanged后面
     * 当你加载完数据的时候，调用这个notifyDidLoad()
     * 才会隐藏头部，并初始化数据等
     */
    public void notifyDidLoad()
    {
        mUIHandler.sendEmptyMessage(WHAT_DID_LOAD_DATA);
    }

    /**
     * 通知已经刷新完了，要放在Adapter.notifyDataSetChanged后面
     * 当你执行完刷新任务之后，调用这个notifyDidRefresh()
     * 才会隐藏掉头部文件等操作
     */
    public void notifyDidRefresh()
    {
        mUIHandler.sendEmptyMessage(WHAT_DID_REFRESH);
    }

    /**
     * 通知已经获取完更多了，要放在Adapter.notifyDataSetChanged后面
     * 当你执行完更多任务之后，调用这个notyfyDidMore()
     * 才会隐藏加载圈等操作
     */
    public void notifyDidMore()
    {
        mUIHandler.sendEmptyMessage(WHAT_DID_MORE);
    }

    /**
     * 设置监听器
     * 
     * @param listener
     */
    public void setOnPullDownListener(OnPullDownListener listener)
    {
        mOnPullDownListener = listener;
    }

    /**
     * 获取内嵌的listview
     * 
     * @return ScrollOverListView
     */
    public ListView getListView()
    {
        return mListView;
    }

    /**
     * 是否开启自动获取更多
     * 自动获取更多，将会隐藏footer，并在到达底部的时候自动刷新
     * 
     * @param index
     *            倒数第几个触发
     */
    public void enableAutoFetchMore(boolean enable, int index)
    {
        if (enable)
        {
            mListView.setBottomPosition(index);
            mFooterLoadingView.setVisibility(View.VISIBLE);
            mFooterTextView.setText("继续上滑以获取更多");
            mFooterLoadingView.setVisibility(View.GONE);
        }
        else
        {
            mFooterTextView.setText("更多");
            mFooterLoadingView.setVisibility(View.GONE);
        }
        mEnableAutoFetchMore = enable;
    }

    /*
     * ==================================
     * Private method
     * 具体实现下拉刷新等操作
     * 
     * ==================================
     */

    /**
     * 初始化界面
     */
    private void initHeaderViewAndFooterViewAndListView(Context context)
    {
        setOrientation(LinearLayout.VERTICAL);
        // setDrawingCacheEnabled(false);
        /*
         * 自定义头部文件
         * 放在这里是因为考虑到很多界面都需要使用
         * 如果要修改，和它相关的设置都要更改
         */
        mHeaderView = LayoutInflater.from(context).inflate(
                R.layout.pulldown_header, null);
        mHeaderViewParams = new LayoutParams(LayoutParams.MATCH_PARENT,
                                             LayoutParams.WRAP_CONTENT);
        addView(mHeaderView, 0, mHeaderViewParams);

        mHeaderTextView = (TextView) mHeaderView.findViewById(R.id.pulldown_header_text);
        mHeaderLoadingView = mHeaderView.findViewById(R.id.pulldown_header_loading);
        mHeaderTextView.setVisibility(View.GONE);
        /**Loading 动画**/
        AnimationDrawable anim = null;
        Object ob = mHeaderLoadingView.getBackground();
        anim = (AnimationDrawable) ob;
        anim.stop();
        anim.start();

        /**
         * 自定义脚部文件
         */
        mFooterView = LayoutInflater.from(context).inflate(
                R.layout.pulldown_footer, null);
        mFooterTextView = (TextView) mFooterView.findViewById(R.id.pulldown_footer_text);
        mFooterLoadingView = mFooterView.findViewById(R.id.pulldown_footer_loading);
        mFooterView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v)
            {
                if (!mIsFetchMoreing)
                {
                    mIsFetchMoreing = true;
                    mFooterLoadingView.setVisibility(View.VISIBLE);
                    /**Loading 动画**/
                    AnimationDrawable anim1 = null;
                    Object ob1 = mFooterLoadingView.getBackground();
                    anim1 = (AnimationDrawable) ob1;
                    anim1.stop();
                    anim1.start();
                    
                    mOnPullDownListener.onMore();
                }
            }
        });

        /*
         * ScrollOverListView 同样是考虑到都是使用，所以放在这里
         * 同时因为，需要它的监听事件
         */
        mListView = new ScrollOverListView(context);
        mListView.setOnScrollOverListener(this);
        mListView.setCacheColorHint(R.color.transparent_color_0);
        mListView.setSelector(R.drawable.lv_select_color_selector);
        mListView.setDivider(getResources().getDrawable(R.drawable.icon_set_listdiv));
        mListView.setEmptyView(findViewById(R.id.empty_tv));
        addView(mListView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

        // 空的listener
        mOnPullDownListener = new OnPullDownListener() {
            @Override
            public void onRefresh()
            {
            }

            @Override
            public void onMore()
            {
            }
        };
    }

    /**
     * 在下拉和回推的时候检查头部文件的状态</br>
     * 如果超过了默认高度，就显示松开可以刷新，
     * 否则显示下拉可以刷新
     */
    private void checkHeaderViewState()
    {
        if (mHeaderViewParams.height >= DEFAULT_HEADER_VIEW_HEIGHT)
        {
            if (mHeaderViewState == HEADER_VIEW_STATE_OVER_HEIGHT)
                return;
            mHeaderViewState = HEADER_VIEW_STATE_OVER_HEIGHT;
            mHeaderTextView.setText("松开可以刷新");
        }
        else
        {
            if (mHeaderViewState == HEADER_VIEW_STATE_NOT_OVER_HEIGHT
                    || mHeaderViewState == HEADER_VIEW_STATE_IDLE)
                return;
            mHeaderViewState = HEADER_VIEW_STATE_NOT_OVER_HEIGHT;
            mHeaderTextView.setText("下拉可以刷新");
        }
    }

    private void setHeaderHeight(final int height)
    {
        mHeaderIncremental = height;
        mHeaderViewParams.height = height;
        mHeaderView.setLayoutParams(mHeaderViewParams);
    }

    /**
     * 自动隐藏动画
     * 
     * @author
     */
    class HideHeaderViewTask extends TimerTask
    {
        @Override
        public void run()
        {
            if (mIsDown)
            {
                cancel();
                return;
            }
            mHeaderIncremental -= AUTO_INCREMENTAL;
            if (mHeaderIncremental > 0)
            {
                mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
            }
            else
            {
                mHeaderIncremental = 0;
                mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
                cancel();
            }
        }
    }

    /**
     * 自动显示动画
     * 
     * @author
     */
    class ShowHeaderViewTask extends TimerTask
    {

        @Override
        public void run()
        {
            if (mIsDown)
            {
                cancel();
                return;
            }
            mHeaderIncremental -= AUTO_INCREMENTAL;
            if (mHeaderIncremental > DEFAULT_HEADER_VIEW_HEIGHT)
            {
                mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
            }
            else
            {
                mHeaderIncremental = DEFAULT_HEADER_VIEW_HEIGHT;
                mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
                if (!mIsRefreshing)
                {
                    mIsRefreshing = true;
                    mUIHandler.sendEmptyMessage(WHAT_ON_REFRESH);
                }
                cancel();
            }
        }
    }

    private Handler mUIHandler = new Handler() {

        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case WHAT_DID_LOAD_DATA:
                {
                    mHeaderViewParams.height = 0;
                    mHeaderLoadingView.setVisibility(View.GONE);
                    mHeaderTextView.setVisibility(View.VISIBLE);
                    mHeaderTextView.setText("下拉可以刷新");
                    showFooterView();
                    return;
                }

                case WHAT_ON_REFRESH:
                {
                    mHeaderLoadingView.setVisibility(View.VISIBLE);
                    
                    /**Loading 动画**/
                    AnimationDrawable anim = null;
                    Object ob = mHeaderLoadingView.getBackground();
                    anim = (AnimationDrawable) ob;
                    anim.stop();
                    anim.start();
                    
                    mHeaderTextView.setText("更新中...");
                    mHeaderTextView.setVisibility(View.GONE);
                    mOnPullDownListener.onRefresh();
                    return;
                }

                case WHAT_DID_REFRESH:
                {
                    mIsRefreshing = false;
                    mHeaderViewState = HEADER_VIEW_STATE_IDLE;
                    mHeaderLoadingView.setVisibility(View.GONE);
                    mHeaderTextView.setVisibility(View.VISIBLE);
                    mHeaderTextView.setText("下拉可以刷新");
                    setHeaderHeight(0);
                    showFooterView();
                    return;
                }

                case WHAT_SET_HEADER_HEIGHT:
                {
                    setHeaderHeight(mHeaderIncremental);
                    return;
                }

                case WHAT_DID_MORE:
                {
                    mIsFetchMoreing = false;
                    mFooterTextView.setVisibility(View.VISIBLE);
                    mFooterTextView.setText("继续上滑以获取更多");
                    mFooterLoadingView.setVisibility(View.GONE);
                }
            }
        }

    };

    /**
     * 显示脚步脚部文件
     */
    private void showFooterView()
    {
        if (mListView.getFooterViewsCount() == 0 && isFillScreenItem())
        {
            mListView.addFooterView(mFooterView);
            mListView.setAdapter(mListView.getAdapter());
        }
    }

    /**
     * 条目是否填满整个屏幕
     */
    private boolean isFillScreenItem()
    {
        final int firstVisiblePosition = mListView.getFirstVisiblePosition();
        final int lastVisiblePostion = mListView.getLastVisiblePosition()
                - mListView.getFooterViewsCount();
        final int visibleItemCount = lastVisiblePostion - firstVisiblePosition
                + 1;
        final int totalItemCount = mListView.getCount()
                - mListView.getFooterViewsCount();

        if (visibleItemCount < totalItemCount)
            return true;
        return false;
    }

    /*
     * ==================================
     * 实现 OnScrollOverListener接口
     * 
     * 
     * ==================================
     */

    @Override
    public boolean onListViewTopAndPullDown(int delta)
    {
        if (mIsRefreshing
                || mListView.getCount() - mListView.getFooterViewsCount() == 0)
            return false;

        int absDelta = Math.abs(delta);
        final int i = (int) Math.ceil((double) absDelta / 2);

        mHeaderIncremental += i;
        if (mHeaderIncremental >= 0)
        { // && mIncremental <= mMaxHeight
            setHeaderHeight(mHeaderIncremental);
            checkHeaderViewState();
        }
        return true;
    }

    @Override
    public boolean onListViewBottomAndPullUp(int delta)
    {
        if (!mEnableAutoFetchMore || mIsFetchMoreing)
            return false;
        // 数量充满屏幕才触发
        if (isFillScreenItem())
        {
            mIsFetchMoreing = true;
            mFooterTextView.setText("加载更多中...");
            mFooterTextView.setVisibility(View.GONE);
            mFooterLoadingView.setVisibility(View.VISIBLE);
            mOnPullDownListener.onMore();
            return true;
        }
        return false;
    }

    @Override
    public boolean onMotionDown(MotionEvent ev)
    {
        mIsDown = true;
        mIsPullUpDone = false;
        mMotionDownLastY = ev.getRawY();
        return false;
    }

    @Override
    public boolean onMotionMove(MotionEvent ev, int delta)
    {
        // 当头部文件回推消失的时候，不允许滚动
        if (mIsPullUpDone)
            return true;

        // 如果开始按下到滑动距离不超过误差值，则不滑动
        final int absMotionY = (int) Math.abs(ev.getRawY() - mMotionDownLastY);
        if (absMotionY < START_PULL_DEVIATION)
            return true;

        final int absDelta = Math.abs(delta);
        final int i = (int) Math.ceil((double) absDelta / 2);

        // onTopDown在顶部，并上回推和onTopUp相对
        if (mHeaderViewParams.height > 0 && delta < 0)
        {
            mHeaderIncremental -= i;
            if (mHeaderIncremental > 0)
            {
                setHeaderHeight(mHeaderIncremental);
                checkHeaderViewState();
            }
            else
            {
                mHeaderViewState = HEADER_VIEW_STATE_IDLE;
                mHeaderIncremental = 0;
                setHeaderHeight(mHeaderIncremental);
                mIsPullUpDone = true;
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean onMotionUp(MotionEvent ev)
    {
        mIsDown = false;
        // 避免和点击事件冲突
        if (mHeaderViewParams.height > 0)
        {
            // 判断头文件拉动的距离与设定的高度，小了就隐藏，多了就固定高度
            int x = mHeaderIncremental - DEFAULT_HEADER_VIEW_HEIGHT;
            Timer timer = new Timer(true);
            if (x < 0)
            {
                timer.scheduleAtFixedRate(new HideHeaderViewTask(), 0, 10);
            }
            else
            {
                timer.scheduleAtFixedRate(new ShowHeaderViewTask(), 0, 10);
            }
            return true;
        }
        return false;
    }

}
